package cn.le.studyEnum;

import java.util.EnumMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 职责链设计模式
 *  程序员以多种不同的方式来解决一个问题，然后将它们链接在一起，当一个请求到来时，她遍历这个链，
 *  直到链中的某个解决方案能够处理请求。
 *
 *  邮局模型
 *      邮局需要以尽可能通用的方式来处理每封邮件，并且要不断尝试处理邮件，直到该邮件最终被确定为一封死信。
 *      其中的每次尝试可以看作为一个策略（也是一个设计模式），而完整的处理方式列表就是一个职责链
 *
 */

//邮件
public class Mail {
    //一般交货
    enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,ON5}
    //可扫描的
    enum Scannability {UNSCANABLE,YES1,YES2,YES3,YES4}
    //可读的
    enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4}
    //地址
    enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6}
    //返回地址
    enum ReturnAddress {MISSNG,OK1,OK2,OK3,OK4,OK5}

    GeneralDelivery generalDelivery;
    Scannability scannability;
    Readability readability;
    Address address;
    ReturnAddress returnAdderss;

    static long counter = 0;
    long id = counter++;

    public String toString()
    {
        return "Mail "+id;
    }
    //详细资料
    public String details()
    {
        return toString()+
                "\n,General Delivery: " + generalDelivery +
                "\n,Address Scanability: " + scannability +
                "\n,Adddress Readability: " + readability +
                "\n,Address Adderss: " + address +
                "\n,Return adderss: " + returnAdderss;
    }
    //随机一个邮件
    public static Mail randomMail()
    {
        Mail mail = new Mail();
        mail.generalDelivery = RandomEnums.random(GeneralDelivery.class);
        mail.scannability = RandomEnums.random(Scannability.class);
        mail.readability = RandomEnums.random(Readability.class);
        mail.address = RandomEnums.random(Address.class);
        mail.returnAdderss = RandomEnums.random(ReturnAddress.class);

        return mail;
    }
    //生产邮件
    public static Iterable<Mail> generator(final int count)
    {
        return new Iterable<Mail>() {
            int n = count;
            @Override
            public Iterator<Mail> iterator() {
                return new Iterator<Mail>() {
                    @Override
                    public boolean hasNext() {
                        return n-- > 0;
                    }

                    @Override
                    public Mail next() {
                        return randomMail();
                    }
                    public void remove()
                    {
                     throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }
}
//邮局
class PostOffice {
    enum MailHandler{
        GENERAL_DELIVERY{
            boolean handle(Mail m)
            {
                switch (m.generalDelivery)
                {
                    case YES:
                        System.out.println("使用一般交货 " + m);
                        return true;
                    default: return false;
                }
            }
        },
        MACHINE_SCAN{
            boolean handle(Mail m)
            {
                switch (m.scannability)
                {
                    case UNSCANABLE:
                        return false;
                    default:
                        System.out.println("提供 " + m + " 自动");
                        return true;
                }
            }
        },
        VISUAL_INSPECTION{
            boolean handle(Mail m)
            {
                switch (m.readability)
                {
                    case ILLEGIBLE:
                        return false;
                    default:
                        System.out.println("提供 "+ m + " 正常的");
                        return true;
                }
            }
        },
        RETURN_TO_SENDER{
            boolean handle(Mail m)
            {
                switch (m.returnAdderss)
                {
                    case MISSNG:
                        return false;
                    default:
                        System.out.println("返回 "+ m + "寄件人");
                        return true;
                }
            }
        };

        abstract boolean handle(Mail m);
    }

    static void handle(Mail m)
    {
        for (MailHandler handle : MailHandler.values()) {
            if(handle.handle(m))
            {
                return;
            }
        }
        System.out.println(m + " 是一張白紙");
    }

    public static void main(String[] args) {

        for (Mail mail: Mail.generator(10) ) {
            System.out.println(mail.details());
            handle(mail);
            System.out.println("****************");
        }

    }
}

/**
 * 利用enumMap 实现邮局的校验功能
 */
class PostOffice2{

    enum MailHandler{GENERAL_DELIVERY,MACHINE_SCAN,VISUAL_INSPECTION,RETURN_TO_SENDER}

    interface Handle{

        boolean handle(Mail m);
    }
    static EnumMap<MailHandler,Handle> enumMap = new EnumMap<MailHandler, Handle>(MailHandler.class);

    static
    {
        enumMap.put(MailHandler.GENERAL_DELIVERY, new Handle() {
            @Override
            public boolean handle(Mail m) {
                switch (m.generalDelivery)
                {
                    case YES:
                        System.out.println("使用一般交货 " + m);
                        return true;
                    default: return false;
                }
            }
        });
        enumMap.put(MailHandler.MACHINE_SCAN, new Handle() {
            @Override
            public boolean handle(Mail m) {
                switch (m.scannability)
                {
                    case UNSCANABLE:
                        return false;
                    default:
                        System.out.println("提供 " + m + " 自动");
                        return true;
                }
            }
        });
        enumMap.put(MailHandler.VISUAL_INSPECTION, new Handle() {
            @Override
            public boolean handle(Mail m) {
                switch (m.readability)
                {
                    case ILLEGIBLE:
                        return false;
                    default:
                        System.out.println("提供 "+ m + " 正常的");
                        return true;
                }
            }
        });
        enumMap.put(MailHandler.RETURN_TO_SENDER, new Handle() {
            @Override
            public boolean handle(Mail m) {
                switch (m.returnAdderss)
                {
                    case MISSNG:
                        return false;
                    default:
                        System.out.println("返回 "+ m + "寄件人");
                        return true;
                }
            }
        });
    }

    static void handle(Mail m)
    {
        for (Map.Entry<MailHandler,Handle> map : enumMap.entrySet()) {
            if(map.getValue().handle(m))
            {
                return;
            }
        }
        System.out.println(m + " 是一張白紙");
    }

    public static void main(String[] args) {

        for (Mail mail: Mail.generator(10) ) {
            System.out.println(mail.details());
            handle(mail);
            System.out.println("****************");
        }

    }
}
